﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;

namespace 学生册成绩管理系统.DAL
{
    // SqlHelper集成了数据库的增删改查的封装
    public class SqlHelper
    {
        public string ConnectionString { get; }
        public SqlConnection Connection { get; }
        public SqlHelper()
        {
            ConnectionString = ConfigurationManager.ConnectionStrings["StudentDBString"].ConnectionString;
            Connection = new SqlConnection(ConnectionString);
        }

        public DataSet ExecuteDataSet(string commandText, params SqlParameter[] parameters)
        {
            return ExecuteDataSet(Connection, CommandType.Text, commandText, parameters);
        }

        public DataSet ExecuteDataSet(SqlConnection connection,CommandType commandType,string commandText,params SqlParameter[] parameters)
        {
            if (connection == null) { throw new ArgumentNullException("SqlConnection is not null"); }
            SqlCommand sqlCommand = connection.CreateCommand();
            PrepareCommand(sqlCommand, commandType, commandText, parameters);
            using (SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand))
            {
                DataSet dataSet = new DataSet();
                adapter.Fill(dataSet);
                return dataSet;
            }
            
        }

        // 预处理
        private void PrepareCommand(SqlCommand sqlCommand, CommandType commandType, string commandText, SqlParameter[] parameters)
        {
            if (Connection.State != ConnectionState.Open)
            {
                Connection.Open();
            }
            sqlCommand.CommandText = commandText;
            sqlCommand.CommandType = System.Data.CommandType.Text;
            //sqlCommand.Connection = Connection;
            if (parameters != null && parameters.Length > 0)
            {
                AttchParameters(sqlCommand, parameters);
            }
        }

        private void AttchParameters(SqlCommand sqlCommand, SqlParameter[] parameters)
        {
            if (sqlCommand == null) throw new ArgumentNullException("SqlCommand不能为空");
            if (parameters == null) throw new ArgumentNullException("parameters");

            // 这里也可以用AddRange，不用循环遍历了
            // sqlCommand.Parameters.AddRange(parameters);
            foreach (var item in parameters)
            {
                if (item != null)
                {
                    if (item.Value == null)
                    {
                        item.Value = DBNull.Value;
                    }

                    sqlCommand.Parameters.Add(item);
                }
            }
        }

        // DataSet转换为List
        public List<T> DataSetToList<T>(DataSet dataSet, int index = 0)
        {
            // 初始化一个空数组
            List<T> list = new List<T>();

            // 断言
            if (dataSet == null || dataSet.Tables.Count <= 0)
            {
                return list;
            }
            if (index > dataSet.Tables.Count - 1 || index < 0)
            {
                return list;
            }

            // DataSet转换成List<T>数组
            // 首先拿到要转换的表
            DataTable dataTable = dataSet.Tables[index];
            // 然后一行一行的把表格里面数据读出来
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                // 这里的t就是Student实例   创建对象
                T t = (T)Activator.CreateInstance(typeof(T));
                // 获取属性，propertyInfos为属性集合
                PropertyInfo[] propertyInfos = t.GetType().GetProperties();
                foreach (var p in propertyInfos)
                {
                    // 把所有列遍历一遍
                    for (int j = 0; j < dataTable.Columns.Count; j++)
                    {
                        // 当前属性是否等于数据库中的列名
                        if (p.Name.Equals(dataTable.Columns[j].ColumnName))
                        {
                            // 判断当前是否为空
                            if (dataTable.Rows[i][j] != DBNull.Value)
                            {
                                // 真正开始转换
                                // 将当前行当前列的值转换给t.p
                                try
                                {
                                    // 将 DataTable 中的数据映射到类型 T (也就是Student)的对象属性
                                    p.SetValue(t, Convert.ChangeType(dataTable.Rows[i][j], p.PropertyType), null);
                                }
                                catch
                                {
                                    
                                }
                            }
                        }
                    }
                }
                list.Add(t);
            }



            return list;
        }


        // 执行SQL语句（Insert，Update，Delete）
        public int ExecuteNonQuery(string commandText, params SqlParameter[] parameters)
        {
            if (Connection == null) throw new ArgumentNullException("SqlConnection不能为空");
            SqlCommand sqlCommand = Connection.CreateCommand();
            PrepareCommand(sqlCommand, CommandType.Text, commandText, parameters);
            int count = sqlCommand.ExecuteNonQuery();
            return count;
        }



        //var connectionString = ConfigurationManager.ConnectionStrings["StudentDBString"].ConnectionString;

        // 第一步，连接并打开数据库
        // 创建一个 SqlConnection 对象，使用 connectionString 来初始化与数据库的连接。
        //SqlConnection sqlConnection = new SqlConnection(ConnectionString);
        //sqlConnection.Open();

        //// 创建一个 SqlCommand 对象，用于执行 SQL 命令
        //SqlCommand sqlCommand = sqlConnection.CreateCommand();
        //// 将字符串转化为sql命令
        //sqlCommand.CommandText = "SELECT  [Id] ,[Name] ,[Password] ,[Sex],[City],[InsertDate] FROM [Student]";
        //sqlCommand.CommandType = System.Data.CommandType.Text;
        //sqlCommand.Connection = sqlConnection;

        //// 创建一个 SqlDataAdapter 对象，用于填充 DataSet 对象
        //// 主要负责执行 SQL 命令并获取数据，然后将这些数据转换并填充到 DataSet 或 DataTable 对象中
        //SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand);

        //DataSet dataSet = new DataSet();
        ////将 SQL 查询的结果填充到 dataSet 对象中
        //sqlDataAdapter.Fill(dataSet);

        //// 这句话很重要，就是把dataSet中第一张表的内容赋值到Datagrid中的ItemsSource
        //this.datagrid.ItemsSource = dataSet.Tables[0].DefaultView;

        //sqlConnection.Close();
        //sqlDataAdapter.Dispose();

    }
}
